﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Practices.Unity;
using MiniStock.Database;
using MiniStock.Entities.Common;
using MiniStock.Entities.Common.Events;
using MiniStock.Infrastructure;
using System.Diagnostics;
using MiniStock.Infrastructure.Configurator;
using MiniStock.Infrastructure.Queue;

namespace MiniStock.BusinessLogic.EntityPersister
{
    public class EntityPersisterWorker : QueuedEventWorkerBase
    {
        [Dependency]
        public EntityDbContext DbContext { get; set; }

        public override void ProcessMessage(EntityEventBase message)
        {
            Debug.Assert(message is ResultEvent, "Only result events should be routed to persister");
            
            try
            {
                // Process message
                var entity = this.DbContext.GetEntityByHash(message.GetEntityHash());

                // for construction messages, add a new entity
                if (entity == null)
                {
                    entity = ((ResultEvent) message).Entity;
                    this.DbContext.Set(entity.GetType()).Add(entity);
                } else
                {
                    entity.CopyFrom(((ResultEvent) message).Entity);
                }

                this.DbContext.SaveChanges();
                var result = message.GetCorrelatedResultEvent<MessagePersistedEvent>(entity);
                // Preserve correlated event id
                result.CorrelatedEventId = message.CorrelatedEventId ?? result.CorrelatedEventId;
                result.SenderAddress = this.Name;

                OutputEventQueue.Enqueue(result);
            }
            catch (Exception ex)
            {
                Trace.TraceError("{0}", ex);
            }
        }
    }
}
